﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;
using System.Windows;

namespace _3DTest
{
   public class Cylinder
    {
        #region Private Helpers
        /// <summary>
        /// Private helper methods
        /// </summary>
        private static Point3D GetPosition(double theta, double phi, double radius)
        {
            double x = radius * Math.Sin(theta) * Math.Sin(phi);
            double y = radius * Math.Cos(phi);
            double z = radius * Math.Cos(theta) * Math.Sin(phi);

            return new Point3D(x, y, z);
        }

        private static Vector3D GetNormal(double theta, double phi)
        {
            return (Vector3D)GetPosition(theta, phi, 1.0);
        }

        private static double DegToRad(double degrees)
        {
            return (degrees / 180.0) * Math.PI;
        }

        private static Point GetTextureCoordinate(double theta, double phi)
        {
            Point p = new Point(theta / (2 * Math.PI),
                                phi / (Math.PI));

            return p;
        }
        #endregion

        #region Public Methods

        /// <summary>
        /// Tessellates the sphere and returns a MeshGeometry3D representing the 
        /// tessellation based on the given parameters
        /// </summary>
        /// <param name="tDiv">theta Divisions</param>
        /// <param name="pDiv">phi divisions</param>
        /// <param name="radius">radius</param>
        public static MeshGeometry3D Create(Point3D p1, Point3D p2, double R)
        {

            Vector3D CircleVector = p1 - p2;

            MeshGeometry3D mesh = new MeshGeometry3D();

            Vector3D M = new Vector3D(1,1,1);
            if (Vector3D.AngleBetween(M, CircleVector ) < 0.1)
                M = new Vector3D(1, 0, 0);

            Vector3D A = Vector3D.CrossProduct(CircleVector, M);
            Vector3D B = Vector3D.CrossProduct(CircleVector, A);
            A.Normalize();
            B.Normalize();
            double Stacks=30;
            double theta;
         Point3D Pos1, Pos2;
 
                  //设圆与 xz 轴平行
         for(int i=0;i<Stacks;i++)
	        {
                   //For i As Integer = 0 To Stacks
 
                    //计算剖分三角形顶点在参数方程中对应的角度
                     theta = i / Stacks * Math.PI * 2;
 
                     Pos1 = R * (A * Math.Cos(theta) + B * Math.Sin(theta)) + p1;
                     Pos2 = R * (A * Math.Cos(theta) + B * Math.Sin(theta)) + p2;
 
                     mesh.Positions.Add(Pos1);
                     mesh.Positions.Add(Pos2);

                     mesh.TextureCoordinates.Add(new Point(i / Stacks, 0));
                     mesh.TextureCoordinates.Add(new Point(i / Stacks, 1));
                 //Next 
	        }
 
            for (int i = 0; i < Stacks-1; i++)
			{
			       // For i As Integer = 0 To Stacks - 1
             mesh.TriangleIndices.Add(i * 2);
             mesh.TriangleIndices.Add(i * 2 + 1);
             mesh.TriangleIndices.Add(i * 2 + 3);
 
            mesh.TriangleIndices.Add(i * 2);
             mesh.TriangleIndices.Add(i * 2 + 3);
             mesh.TriangleIndices.Add(i * 2 + 2);
       //  Next 
			}
 

            mesh.Freeze();
            return mesh;
        }
        #endregion
    }
}
